let Cesium:any=undefined;

/**
 * 流动线材质
 * @global
 * @param {object} options
 * @param {number} options.duration - 持续时长
 * @param {Color} options.color - 颜色
 * @example
 * import { Graphics } from 'cesium_dev_kit'
 * const graphicObj = new Graphics({
 *     cesiumGlobal: Cesium,
 *     containerId: 'cesiumContainer'
 * })
 *const polylineMaterial =  new Cesium.Scene.PolylineFlowMaterialProperty({
        color: new Cesium.Color(77 / 255, 201 / 255, 255 / 255, 1),
        duration: 200
      })
 * graphicObj.graphics.getLineGraphics({
        positions:Cesium.Cartesian3.fromDegreesArray([
              104.09816110606057,
              30.659821965447698,
              104.1120972824757,
              30.65330300319938,
              104.10758419863926,
              30.64592470850288,
              104.09351691196979,
              30.652434826507452,
              104.09816110606057,
              30.659821965447698
            ]),
 *      material:polylineMaterial,
 *      clampToGround:false,
 *      width:1
 * })
 */
export class PolylineFlowMaterialProperty extends Cesium.Property {
    private _definitionChanged: any;
    private _color: any;
    private _colorSubscription: any;
    private _duration: any;
    private _durationSubscription: any;

    constructor(options: any) {
        super()
        options = Cesium.defaultValue(options, Cesium.defaultValue.EMPTY_OBJECT);
        this._definitionChanged = new Cesium.Event();
        this._color = options.color || Cesium.Color.fromBytes(0, 255, 255, 255);
        this._duration = Cesium.defaultValue(options.duration, 45);
    }
    // @ts-ignore
    get isConstant() {
        return false;
    }
    // @ts-ignore
    get definitionChanged() {
        return this._definitionChanged;
    }

    set color(value: any) {
        this._color = value;
    }

    get color() {
        return this._color;
    }

    set duration(value: any) {
        this._duration = value;
    }

    get duration() {
        return this._duration;
    }

    getType() { //'PolylineFlow'
        // @ts-ignore
        return Cesium.Material.PolylineFlowType;
    }

    getValue(time: any, result: any) {
        if (!result) {
            result = {};
        }
        result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
        result.duration = this._duration;
        return result;
    }

    equals(other: any) {
        return (
            this === other || (other instanceof PolylineFlowMaterialProperty && Cesium.Property.equals(this._color, other._color))
        );
    }
}

// 流动线
function _getFlowLineShader(options: any) {
    if (options && options.get) {
        return "uniform vec4 color;\n\
              uniform float duration;\n\
              \n\
              czm_material czm_getMaterial(czm_materialInput materialInput){\n\
                  czm_material material = czm_getDefaultMaterial(materialInput);\n\
                  vec2 st = materialInput.st;\n\
                  float t =fract(czm_frameNumber / duration);\n\
                  t *= 1.03;\n\
                  float alpha = smoothstep(t- 0.03, t, st.s) * step(-t, -st.s);\n\
                  alpha += 0.1;\n\
                  vec4 fragColor;\n\
                  fragColor.rgb = (color.rgb) / 0.5;\n\
                  fragColor = czm_gammaCorrect(fragColor);\n\
                  material.diffuse = fragColor.rgb;\n\
                  material.alpha = alpha;\n\
                  material.emission = fragColor.rgb;\n\
                  return material;\n\
              }\n\
              ";
    }

}

const _installFlowMaterial = (CesiumSources:any) => {
    Cesium=CesiumSources;
    // @ts-ignore
    Cesium.Material.PolylineFlowType = "PolylineFlow";
    // @ts-ignore
    Cesium.Scene.PolylineFlowMaterialProperty = PolylineFlowMaterialProperty;
    // @ts-ignore
    Cesium.Material._materialCache.addMaterial(Cesium.Material.PolylineFlowType, {
        fabric: {
            // @ts-ignore
            type: Cesium.Material.PolylineFlowType,
            uniforms: {
                color: new Cesium.Color(1.0, 1.0, 2.0, 0.7),
                duration: 45,
            },
            source: _getFlowLineShader({
                get: true,
            }),
        },
        translucent: function () {
            return true;
        },
    });
}
export {
    _installFlowMaterial
} ;
